package com.mini.auth.config;

import com.mini.auth.provider.SmsAuthenticationProvider;
import com.mini.auth.service.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.util.ArrayList;

/**
 * Provider相关的配置
 * @author Zhou Feng
 */
@Configuration
public class ProviderConfig {
    @Autowired
    private PasswordEncoder encoder;
    @Autowired
    private UserDetailsServiceImpl userDetailsService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    //将自定义的AuthenticationManager注入容器
    @Bean
    public AuthenticationManager authenticationManager() {
        //配置需要的Provider,refresh_token模式不需要手动添加就可以使用
        ArrayList<AuthenticationProvider> providers = new ArrayList<>();
        //password模式需要 DaoAuthenticationProvider，必须手动添加。其他自带的授权模式无需手动添加。
        providers.add(daoAuthenticationProvider());
        //添加自定义的AuthenticationProvider
        providers.add(smsAuthenticationProvider());
        return new ProviderManager(providers);
    }

    public SmsAuthenticationProvider smsAuthenticationProvider(){
        SmsAuthenticationProvider smsAuthenticationProvider = new SmsAuthenticationProvider();
        smsAuthenticationProvider.setUserDetailsService(userDetailsService);
        smsAuthenticationProvider.setRedisTemplate(redisTemplate);
        return smsAuthenticationProvider;
    }

    //处理”password模式“和”授权码模式“和”验证client“时
    //都会调用 DaoAuthenticationProvider的实例，不过三者调用的是不同对象。
    public DaoAuthenticationProvider daoAuthenticationProvider(){
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(encoder);
        return provider;
    }
}
